﻿/*
 * Nix PBEM Game Engine.
 * Copyright (C) 2008, Lauris Bukšis-Haberkorns
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.

 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.

 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

using System;
using System.Collections.Generic;
using System.Text;

using Nix.PBeM.Engine.DataTypes;
using Nix.PBeM.Engine.DataTypes.Orders;
using Nix.PBeM.Engine.DataSources;

namespace Nix.PBeM.Engine.Process.Orders
{
	class AtOrder : OrderBase
	{
		/// <summary>
		/// Initializes a new instance of the <see cref="AtOrder"/> class.
		/// </summary>
		public AtOrder()
			: base ("AT")
		{
			this.Syntax = string.Format("{0} location-id|structure-id", this.Keyword);
			this.Description = @"This order executes when the unit is at the location specified. If a structure id is specified, it executes when the location is entered; if a location id is specified and the unit is in a structure at the location, the order is not executed.";
			this.Type = OrderType.Immediate;
			this.MayInterrupt = true;
		}

		/// <summary>
		/// Initializes a new instance of the <see cref="AtOrder"/> class.
		/// </summary>
		/// <param name="entity">The entity.</param>
		public AtOrder ( OrderEntity entity, StringLineParser parser )
			: this ()
		{
			this.Entity = entity;
			this.Parser = parser;
		}

		/// <summary>
		/// Create order instance.
		/// </summary>
		/// <param name="entity">The entity.</param>
		/// <returns>Order instance.</returns>
		public override OrderBase Create ( OrderEntity entity, StringLineParser parser )
		{
			return new AtOrder(entity, parser);
		}
		
		private Location location = null;

		// TODO: Implement structures
		//private Structure structure = null;

		/// <summary>
		/// Parses this order.
		/// </summary>
		public override void Parse ()
		{
			if (this.Entity.GetType() != typeof(Unit))
				throw new OrderParseException("This order can be specified only for unit.");

			string tag = this.Parser.GetOptionalWord();
			if ( string.IsNullOrEmpty(tag) )
				throw new OrderParseException("You must specify either location or structure id.");
			this.location = Engine.Instance.FindLocation(tag);
			//this.structure = Engine.Instance.FindStructure(tag);
			
			if (this.location == null/* && this.structure == null*/)
				throw new OrderParseException("You must specify either location or structure id.");

			this.Valid = true;
		}

		/// <summary>
		/// Order duration.
		/// </summary>
		/// <value></value>
		public override int Duration
		{
			get
			{
				return base.Duration;
			}
			set
			{
				// Allow setting only duration 1 or permanent
				if ( value > 1 )
					base.Duration = 1;
				else
					base.Duration = value;
			}
		}

		public override string ToString ()
		{
			return base.ToString() + " " + (this.location != null ? this.location.Tag : ""/*this.structure.Tag*/);
		}

		/// <summary>
		/// Executes this order.
		/// </summary>
		/// <returns>
		/// 	<c>true</c> if order was executed successfully; otherwise, <c>false</c>
		/// </returns>
		public override void Execute ()
		{
			base.Execute();
			// If order is not valid just end execution.
			if ( ! this.IsValid )
				return;
			if ( (((Unit)this.Entity).Location == this.location/* && ((Unit)this.Entity).Structure == null*/) /*||
					(((Unit)this.Entity).Structure != null && ((Unit)this.Entity).Structure == this.structure*/  )
				this.CompleteExecution();
			else
				this.ExecutionFailed = true;
		}
	}
}